#pragma once
#include <iostream>
#include <memory>
#include <sstream>
#include <jsoncpp/json/json.h>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "log.hpp"

class JsonUtil
{
public:
    static void Serialization(const Json::Value &root, std::string &str)
    {
        Json::StreamWriterBuilder swb;
        //swb["indentation"] = "";
        std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
        std::stringstream ss;
        sw->write(root, &ss);
        str = ss.str();
    }
    static bool DeSerialization(const std::string &str, Json::Value &root)
    {
        Json::CharReaderBuilder crb;
        std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
        std::string errstr;
        if (cr->parse(str.c_str(), str.c_str() + str.size(), &root, &errstr) == false)
        {
            Log(ERROR, "DeSerialization error : %s", errstr.c_str());
            return false;
        }
        return true;
    }
};

class StrUtil
{
public:
    static int split(const std::string& src, const std::string& sep, std::vector<std::string>& ret)
    {
        size_t left = 0, pos = 0;
        while(pos != std::string::npos)
        {
            pos = src.find(sep, left);
            if(pos != left)
                ret.push_back(src.substr(left, pos - left));
            left = pos + 1;
        }
        return ret.size();
    }
};

class FileUtil
{
public:
    static std::string readFile(const std::string& filename)
    {
        std::string ret;
        std::ifstream fd(filename, std::ios::in | std::ios::binary);
        if(!fd.is_open())
        {
            Log(WARNING, "the file[%s] is not find", filename.c_str());
            return "";
        }
        struct stat st;
        if(stat(filename.c_str(), &st) == 0)
        {
            //是目录文件也直接返回错误
            if(S_ISDIR(st.st_mode))
            {
                return "";
            }

            ret.resize(st.st_size);
            fd.read(&ret[0], st.st_size);
        }
        fd.close();
        return ret;
    }
};